package com.weixing.oauth2.common.oauth2.integration.authenticator.captcha;

import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.oauth2.common.constants.SecurityConstants;
import com.weixing.oauth2.common.oauth2.integration.IntegrationAuthentication;
import com.weixing.oauth2.common.oauth2.integration.authenticator.AbstractPreparableIntegrationAuthenticator;
import com.weixing.oauth2.common.userdetails.IUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 图形验证码验证码集成认证
 *
 * @author LIQIU
 * @date 2018-3-31
 **/
@Component
@Slf4j
public class CaptchaIntegrationAuthenticator extends AbstractPreparableIntegrationAuthenticator implements ApplicationEventPublisherAware {

    @Autowired
    private IUserDetailsService customUserDetailsService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private PasswordEncoder passwordEncoder;

    private ApplicationEventPublisher applicationEventPublisher;

    private final static String SMS_AUTH_TYPE = "captcha";

    @Override
    public UserDetails authenticate(IntegrationAuthentication integrationAuthentication, HttpServletRequest request) {
        //获取用户名，实际值是手机号
        String username = integrationAuthentication.getUsername();
        //通过手机号码查询用户
        return this.customUserDetailsService.loadUserByUsername(username);
    }

    @Override
    public void prepare(IntegrationAuthentication integrationAuthentication, HttpServletRequest request) {
        String key = GlobalConstant.REDIS_PRE_CODE + request.getHeader(GlobalConstant.FIELD_UTOKEN);
        String verifyCode_redis = stringRedisTemplate.opsForValue().get(key);

        if (StringUtils.isBlank(verifyCode_redis)){
            throw new OAuth2Exception("验证码错误或已过期");
        }
        String verifyCode = request.getParameter(SecurityConstants.DEFAULT_PARAMETER_NAME_CODE_IMAGE);
        if (verifyCode.equalsIgnoreCase(verifyCode_redis)){
            // 校验通过清除redis
            stringRedisTemplate.delete(key);
        }else{
            throw new OAuth2Exception("验证码验证失败");
        }
    }

    @Override
    public boolean support(IntegrationAuthentication integrationAuthentication) {
        return SMS_AUTH_TYPE.equals(integrationAuthentication.getAuthType());
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    @Override
    public void complete(IntegrationAuthentication integrationAuthentication, HttpServletRequest request) {
        super.complete(integrationAuthentication, request, this.customUserDetailsService);
    }
}
